return FALSE;
}
+static void
+restack_children (GdkSurface *window)
+{
+ GList *popup;
+
+ for (popup = window->children; popup; popup = popup->next)
+ {
+ GdkSurface *child = GDK_SURFACE (popup->data);
+ /* Windows doesn't have a function to put window A *above* window B.
+ * Instead we put window A immediately *below* window B,
+ * then put window B immediately below window A.
+ * SWP_NOSENDCHANGING prevents our own handler from triggering.
+ */
+ SetWindowPos (GDK_SURFACE_HWND (child), GDK_SURFACE_HWND (window), 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
+ g_print ("Put popup %p (%p) above %p (%p)\n", child, GDK_SURFACE_HWND (child), window, GDK_SURFACE_HWND (window));
+ SetWindowPos (GDK_SURFACE_HWND (window), GDK_SURFACE_HWND (child), 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER);
+ }
+}
+
static void
ensure_stacking_on_unminimize (MSG *msg)
{
if (lowest_transient != NULL)
{
GDK_NOTE (EVENTS,
- g_print (" restacking %p above %p",
+ g_print (" restacking %p below %p",
msg->hwnd, lowest_transient));
SetWindowPos (msg->hwnd, lowest_transient, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER);
impl->type_hint == GDK_SURFACE_TYPE_HINT_DIALOG ||
impl->transient_owner != NULL)
{
+ GdkSurface *child = window;
+ GdkSurface *owner = impl->transient_owner;
+
SetWindowPos (msg->hwnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER);
+ /* Bing the whole hierarchy of transients back up */
+ while (owner != NULL)
+ {
+ SetWindowPos (GDK_SURFACE_HWND (owner), GDK_SURFACE_HWND (child), 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER);
+ restack_children (owner);
+ child = owner;
+ owner = GDK_WIN32_SURFACE (owner)->transient_owner;
+ }
return;
}
((window_ontop && rover_ontop) || (!window_ontop && !rover_ontop)))
{
GDK_NOTE (EVENTS,
- g_print (" restacking %p above %p",
+ g_print (" restacking %p below %p",
msg->hwnd, rover));
SetWindowPos (msg->hwnd, rover, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER);
transient-type windows. */
if (!(old_state & GDK_SURFACE_STATE_ICONIFIED) &&
(new_state & GDK_SURFACE_STATE_ICONIFIED))
- ensure_stacking_on_unminimize (msg);
+ {
+ ensure_stacking_on_unminimize (msg);
+ restack_children (window);
+
+ }
}
/* Show, New size or position => configure event */
(LOWORD (msg->wParam) == WA_INACTIVE ? "INACTIVE" : "???"))),
HIWORD (msg->wParam) ? " minimized" : "",
(HWND) msg->lParam));
- if (window->surface_type == GDK_SURFACE_POPUP)
+ if (window->surface_type == GDK_SURFACE_POPUP ||
+ window->surface_type == GDK_SURFACE_TEMP)
{
/* Popups cannot be activated or de-activated -
* they only support keyboard focus, which GTK
break;
}
+ if (LOWORD (msg->wParam) == WA_INACTIVE && msg->lParam != 0)
+ {
+ GdkSurface *other_surface = gdk_win32_handle_table_lookup ((HWND) msg->lParam);
+ if (other_surface != NULL &&
+ (other_surface->surface_type == GDK_SURFACE_POPUP ||
+ other_surface->surface_type == GDK_SURFACE_TEMP))
+ {
+ /* We're being deactivated in favour of some popup or temp window.
+ * Since only toplevels can have visual focus, pretend that
+ * nothing happened.
+ */
+ *ret_valp = 0;
+ return_val = TRUE;
+ break;
+ }
+ }
+
if (LOWORD (msg->wParam) == WA_INACTIVE)
gdk_synthesize_surface_state (window, GDK_SURFACE_STATE_FOCUSED, 0);
else
msg->wParam ? "YES" : "NO",
(gint64) msg->lParam));
if (msg->wParam && GDK_SURFACE_IS_MAPPED (window))
- ensure_stacking_on_activate_app (msg, window);
+ {
+ ensure_stacking_on_activate_app (msg, window);
+ restack_children (window);
+ }
break;
case WM_NCHITTEST:
/* TODO: pass all messages to DwmDefWindowProc() first! */